/*
 * Copyright (C) 2010 Zaizi Limited.
 * 
 * This file is part of Zaizi's Alfresco FISE integration
 * 
 * Alfresco FISE is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Alfresco FISE is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Alfresco FISE. If not, see <http://www.gnu.org/licenses/>.
 */
package org.zaizi.fiseiks.alfresco.service;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

/**
 * Semantic content bean
 * 
 * @author efoncubierta
 *
 */
public class SemanticContent extends BasicContent
{
	private static final long serialVersionUID = -2350496317636797309L;
	
	private String contentUrl;
	private String metadataUrl;
	private Map<String, List<Entity>> entities;
	
	/**
	 * Constructor
	 */
	public SemanticContent()
	{
		// Collections initialization
		entities = new HashMap<String, List<Entity>>();
	}

	/**
	 * Get content URL
	 * 
	 * @return Content URL
	 */
	public String getContentUrl()
	{
		return contentUrl;
	}

	/**
	 * Set content URL
	 * 
	 * @param contentUrl Content URL
	 */
	public void setContentUrl(String contentUrl)
	{
		this.contentUrl = contentUrl;
	}

	/**
	 * Get metadata URL
	 * 
	 * @return Metadata URL
	 */
	public String getMetadataUrl()
	{
		return metadataUrl;
	}

	/**
	 * Set metadata URL
	 * 
	 * @param metadataUrl Metadata URL
	 */
	public void setMetadataUrl(String metadataUrl)
	{
		this.metadataUrl = metadataUrl;
	}

	/**
	 * Get entities
	 * 
	 * @return Entities
	 */
	public Map<String, List<Entity>> getEntities()
	{
		return entities;
	}

	/**
	 * Set entities
	 * 
	 * @param entities Entities
	 */
	public void setEntities(Map<String, List<Entity>> entities)
	{
		this.entities = entities;
	}
	
	/**
	 * Add a new entity
	 * 
	 * @param type Entity type (organisation, place, people...)
	 * @param label
	 * @param reference
	 */
	public void addEntity(String type, String label, String reference)
	{
		Entity entity = new Entity(label, reference);
		if(!entities.containsKey(type)) {
			entities.put(type, new ArrayList<Entity>());
		}
		
		if(!entities.get(type).contains(entity))
		{
			entities.get(type).add(entity);
		}
	}
	
	/**
	 * Convert to a JSON String
	 * 
	 * @return JSON String
	 */
	public String toJSONString()
	{
		return toJSONObject().toString();
	}
	
	/**
	 * Convert to a JSON object
	 * 
	 * @return JSON object
	 */
	public JSONObject toJSONObject()
	{
		final JSONObject obj = new JSONObject();
		
		try
		{
			obj.put("nodeRef", getNodeRef());
			obj.put("contentUrl", contentUrl);
			obj.put("metadataUrl", metadataUrl);
			
			obj.put("entities", new JSONObject());
			
			for(Map.Entry<String, List<Entity>> e : entities.entrySet()) {
				final JSONArray entitiesJson = new JSONArray();
				for(Entity entity : e.getValue()) {
					entitiesJson.put(new JSONObject(entity));
				}
				obj.getJSONObject("entities").put(e.getKey(), entitiesJson);				
			}
		}
		catch (JSONException e)
		{
			// TODO: Nothing to do
		}
		
		return obj;
	}
	
	/**
	 * Semantic entity bean
	 * 
	 * @author efoncubierta
	 *
	 */
	public class Entity implements Serializable
	{
		private static final long serialVersionUID = -2340892940785351584L;
		
		private final String label;
		private final String reference;
		
		/**
		 * Constructor
		 * 
		 * @param label Label
		 * @param reference Reference (URL)
		 */
		public Entity(String label, String reference)
		{
			this.label = label;
			this.reference = reference;
		}

		/**
		 * Get label
		 * 
		 * @return Label
		 */
		public String getLabel()
		{
			return label;
		}

		/**
		 * Get reference
		 * 
		 * @return Reference
		 */
		public String getReference()
		{
			return reference;
		}

		/*
		 * (non-Javadoc)
		 * @see java.lang.Object#equals(java.lang.Object)
		 */
		@Override
		public boolean equals(Object o)
		{
			if(o != null && o instanceof Entity) {
				return this.label.equals(((Entity)o).getLabel());
			}
			return false;
		}
	}
}
